package com.google.code.rsser.service.impl;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.code.rsser.dao.EntryDAO;
import com.google.code.rsser.dao.FeedDAO;
import com.google.code.rsser.model.Entry;
import com.google.code.rsser.model.Feed;
import com.google.code.rsser.model.User;
import com.google.code.rsser.service.EntryService;

@Service(value = "entryService")
@Transactional
public class EntryServiceImpl implements EntryService {

	private Logger logger = Logger.getLogger(EntryServiceImpl.class);
	
	@Autowired
	protected EntryDAO entryDAO;
	
	@Autowired
	protected FeedDAO feedDAO;
	
	public void markAsRead(User user, Integer entryId) {
		Entry entry = entryDAO.get(entryId);
		
		if (logger.isDebugEnabled()) {
			logger.debug("Trying to mark entry [entryId=" + entryId + "] read");
		}
		
		if (!entry.getReadBy().contains(user)) {
			entry.getReadBy().add(user);
			
			entryDAO.save(entry);
			
			if (logger.isDebugEnabled()) {
				logger.debug("Entry [entryId=" + entryId + "] marked as read");
			}
		} else if (logger.isDebugEnabled()) {
			logger.debug("Entry [entryId=" + entryId + "] already read");
		}
	}

	public void markAsUnread(User user, Integer entryId) {
		Entry entry = entryDAO.get(entryId);
		
		if (logger.isDebugEnabled()) {
			logger.debug("Trying to mark entry [entryId=" + entryId + "] unread");
		}
		
		if (entry.getReadBy().contains(user)) {
			entry.getReadBy().remove(user);
			
			entryDAO.save(entry);
			
			if (logger.isDebugEnabled()) {
				logger.debug("Entry [entryId=" + entryId + "] marked as unread");
			}
		} else if (logger.isDebugEnabled()) {
			logger.debug("Entry [entryId=" + entryId + "] already unread");
		}
	}

	public List<Integer> getRead(User user, Integer feedId) {
		Feed feed = feedDAO.get(feedId);
		
		List<Integer> read = new ArrayList<Integer>();
		
		if (feed == null) {
			return read;
		}
		
		for (Entry entry : feed.getEntries()) {
			if (entry.getReadBy().contains(user)) {
				read.add(entry.getId());
			}
		}
		
		if (logger.isDebugEnabled()) {
			logger.debug("Entries marked as read in feed [feedId=" + feedId + "] [" + read + "]");
		}
		
		return read;
	}

	public void markAllAsRead(User user, Integer feedId) {
		if (logger.isDebugEnabled()) {
			logger.debug("Trying to mark all entries in feed [feedId=" + feedId + "] read");
		}
		
		Feed feed = feedDAO.get(feedId);
		
		for (Entry entry : feed.getEntries()) {
			if (!entry.getReadBy().contains(user)) {
				entry.getReadBy().add(user);
	
				if (logger.isDebugEnabled()) {
					logger.debug("Entry [entryId=" + entry.getId() + "] in feed [feedId=" + feedId + "] marked read");
				}
				
				entryDAO.save(entry);
			}
		}
	}

	public void markAllAsUnread(User user, Integer feedId) {
		if (logger.isDebugEnabled()) {
			logger.debug("Trying to mark all entries in feed [feedId=" + feedId + "] unread");
		}
		
		
		Feed feed = feedDAO.get(feedId);
		
		for (Entry entry : feed.getEntries()) {
			if (entry.getReadBy().contains(user)) {
				entry.getReadBy().remove(user);
				
				if (logger.isDebugEnabled()) {
					logger.debug("Entry [entryId=" + entry.getId() + "] in feed [feedId=" + feedId + "] marked unread");
				}
				
				entryDAO.save(entry);
			}
		}	
	}

	public List<Entry> getUnread(User user) {
		return entryDAO.getUnread(user);
	}
	
}
